package com.cwj.mansysback.servlet.impl;

import com.cwj.mansysback.entity.Account;
import com.cwj.mansysback.entity.LocalAccount;
import com.cwj.mansysback.service.api.LocalAccountService;
import com.cwj.mansysback.service.impl.AccountServiceImpl;
import com.cwj.mansysback.service.impl.LocalAccountServiceImpl;
import com.cwj.mansysback.servlet.util.MyUtils;
import com.google.gson.Gson;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.Timestamp;
import java.util.*;

public class LoginServlet extends HttpServlet {

    private static final AccountServiceImpl accService = new AccountServiceImpl();

    private static final LocalAccountService loAccSer = new LocalAccountServiceImpl();

    static String[] keys={"username","password","rank"};



    static String[] resKeys = {"status","message"};

    private static Map<String,LocalAccount> localAccounts= new HashMap<>();

    private static Long maxLong = (long) (1000 * 60 * 60 * 24 * 7);

    private static Long maxCount = (long) (10);

    public static Long getMaxLong() {
        return maxLong;
    }

    public static void setMaxLong(Long maxLong) {
        LoginServlet.maxLong = maxLong;
    }

    public static Long getMaxCount() {
        return maxCount;
    }

    public static void setMaxCount(Long maxCount) {
        LoginServlet.maxCount = maxCount;
    }

    private static class LoginState extends Statement{
        private String idCard;//身份认证

        public LoginState(Integer statue, String message, String idCard) {
            super(statue, message);
            this.idCard = idCard;
        }

        public LoginState(String idCard) {
            this.idCard = idCard;
        }

        public LoginState() {
        }

        public String getIdCard() {
            return idCard;
        }

        public void setIdCard(String idCard) {
            this.idCard = idCard;
        }

        @Override
        public String toString() {

            return  super.toString()+" "+"LoginState{" +
                    "idCard='" + idCard + '\'' +
                    '}';
        }
    }

    @Override
    public void init() throws ServletException {
        super.init();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {



        Account acc = new Account();

        try {
            BeanUtils.populate(acc,req.getParameterMap());
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }

        System.out.println("Login-servlet: "+acc);

        LocalAccount localAccount = new LocalAccount(acc.getAid(),acc.getAccrank(),new Timestamp(new Date().getTime()),null);

        LoginState statue = new LoginState(0,Statement.getMessage(0),null );


        if(! accService.isExist(acc)){
            statue.setStatue(2);
        }else if( ! accService.isTrue(acc)){
            statue.setStatue(1);
        }else{

            String idCard=MyUtils.createKey(128);

            localAccount.setIdCard(idCard);
            statue.setIdCard(idCard);

            LoginServlet.localAccounts.put(statue.getIdCard(),localAccount);
            System.out.println("idCard"+LoginServlet.localAccounts.get(statue.getIdCard()));
            downLocalAccount(new Timestamp(new Date().getTime()));

        }

        System.out.println(acc);

        statue.setMessage(Statement.getMessage(statue.getStatue()));

        System.out.println(Arrays.toString(LoginServlet.localAccounts.keySet().stream().toArray()));

        //将报文自身写入其中
        MyUtils.writeResponse(resp,statue);

    }

    private void downLocalAccount(Timestamp now){

        Map<String,LocalAccount>map=LoginServlet.localAccounts;

        if(map.size() <= maxCount)  return ;

        HashMap<String,LocalAccount>new_map = new HashMap<>();

        ArrayList<LocalAccount> list =new ArrayList<>();

        final Set<String> set = map.keySet();

        for(String str : set){
            list.add(map.get(str));
        }

        list.sort((a,b)->{
            return -Math.toIntExact((a.getLoginTime().getTime() - b.getLoginTime().getTime()));
        });

        // 清理数据库用户
        loAccSer.clearLocalAccount(now,LoginServlet.maxLong);


        for (LocalAccount localAccount : list) {

            if ((now.getTime() - localAccount.getLoginTime().getTime()) > maxLong) break;

            if (new_map.size() < maxCount / 2) {
                new_map.put(localAccount.getIdCard(), localAccount);
            } else {
                loAccSer.addLocalAccount(localAccount);
            }
        }

        LoginServlet.localAccounts=new_map;

    }

    public static LocalAccount loadLoAcc(String idCard){


        LocalAccount res = null;

        res = LoginServlet.localAccounts.get(idCard);

        if(res != null) return res;

        loAccSer.clearLocalAccount(new Timestamp(new Date().getTime()),LoginServlet.maxLong);

        LocalAccount loAcc = loAccSer.getLocalAccount(idCard);

        if(loAcc == null)   return null;

        LoginServlet.localAccounts.put(loAcc.getIdCard(),loAcc);
        return loAcc;
    };

    public static void main(String[] args) {
        Date date=new Date();
        System.out.println(date);
    }

}
